package descentFly.controller
{
	import UIFree.ObjectEvent;
	
	import descentFly.app.radar.df_radarEvent;
	import descentFly.chips.df_chip;
	import descentFly.chips.df_weapont;
	import descentFly.df_space;
	
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Vector3D;
	
	public class df_userController extends FlyController {
		public static const ACTION_FORWARD		: String = 'Forward'; 
		public static const ACTION_BACKWARD		: String = 'Backward'; 
		public static const ACTION_SLIDELEFT	: String = 'SlideLeft';
		public static const ACTION_SLIDERIGHT	: String = 'SlideRight';
		public static const ACTION_LEFTROLL		: String = 'Leftroll'; 
		public static const ACTION_RIGHTROLL	: String = 'Rightroll';
		public static const ACTION_FIRE			: String = 'Fire';
		public static const ACTION_ROTAX		: String = 'RotAX';
		public static const ACTION_ROTDX		: String = 'RotDX';
		public static const ACTION_ROTAY		: String = 'RotAY';
		public static const ACTION_ROTDY		: String = 'RotDY';
		public static const ACTION_NEXTLEVEL	: String = 'ACTION_NEXTLEVEL';
		public static const ACTION_EXITGAME		: String = 'ACTION_EXITGAME';
		public static const ACTION_ROTATE		: String = 'ACTION_ROTATE';
		public static const ACTION_DECLIVE		: String = 'ACTION_DECLIVE';
		public static const ACTION_NOACTIVE		: String = 'ACTION_NOACTIVE';
		public static const ACTION_WEAPONTNEXT	: String = 'ACTION_WEAPONTNEXT';
		public static const ACTION_WEAPONTPREV	: String = 'ACTION_WEAPONTPREV';
		public static const ACTION_WEAPONT		: String = 'ACTION_WEAPONT';
		
		public static const NORESETACTIONS		: Array = [
			ACTION_WEAPONT, ACTION_NOACTIVE
		];
		
		// EVENTS
		public static const ACTION			: String = 'ACTION'; 
		public static const ACTION_REQUIRE	: String = 'ACTION_REQUIRE'; 
		
		private var _curWeapont				: df_weapont;
		
		public function df_userController(a_stage:Stage, 
										  a_space			: df_space,
										  dispatchTarget:EventDispatcher=null, a_options: Object=null) {
			super(a_stage, a_space, dispatchTarget, a_options);
		}
		
		override public function setBody(a_body:df_chip): void {
			super.setBody(a_body);
			body.addEventListener(ACTION_REQUIRE, doActionRequire);
			body.addEventListener(df_chip.CHANGEWEAPONT, doChangeWeapont);
			setWeapont(body.currentWeapont);
		}
		
		override protected function removeEvents():void {
			super.removeEvents();
			if (body) {
				body.removeEventListener(ACTION_REQUIRE, doActionRequire);
				body.removeEventListener(df_chip.CHANGEWEAPONT, doChangeWeapont);
			}
			setWeapont(null);		
		}
		
		protected function doChangeWeapont(e: Event): void {
			if (keyState[ACTION_WEAPONT] != body.weapontIndex) {
				changeActionState(ACTION_WEAPONT, body.weapontIndex);
				setWeapont(body.currentWeapont);
			}
		}
		
		protected function setWeapont(a_chipWeapont: df_weapont): void {
			if (_curWeapont) _curWeapont.removeEventListener(df_weapont.EMPTY_AMMO, doEmptyAmmo);
			_curWeapont = a_chipWeapont;
			if (_curWeapont) _curWeapont.addEventListener(df_weapont.EMPTY_AMMO, doEmptyAmmo);
		}
		
		protected function doEmptyAmmo(e: Event): void {
			changeActionState(ACTION_FIRE, false);
			if (body.setNextWeapont(-1)) body.fire(true);
		}
		
		protected function doActionRequire(e: ObjectEvent): void {
			changeActionState(e.object.action, e.object.state);
		}
		
		protected function resetKeyState(): void {
			for (var i: String in keyState) {
				if ((NORESETACTIONS.indexOf(i) == -1) && keyState[i])
					changeActionState(i, defValue(i));
			}
		}
		
		protected function defValue(action: String): Object {
			if (action == ACTION_ROTATE) return [0,0,0];
			return false;
		}
		
		protected function changeActionState(actionName: String, a_state: Object): void {
			if (keyState[actionName] != a_state) {
				keyState[actionName] = a_state;
				if (action(actionName, a_state)) {
					body.dispatchEvent(new ObjectEvent(ACTION, {
						action	: actionName,
						state	: a_state
					}));
				}
			}
		}
		
		protected function action(actionName: String, state: Object): Boolean {
			if (actionName == ACTION_FIRE) 
				return body.fire(state as Boolean);
			else if (actionName == ACTION_ROTATE) {
				if (state) {
					var v: Vector3D = new Vector3D(state[0], state[1], state[2]);
					v.scaleBy(1/120);
					_rotateRequest = _rotateRequest.add(v);
				}
			} else if (actionName == ACTION_WEAPONT) 
				body.weapontIndex = state as int;
			else if (state) {
				if (actionName == ACTION_DECLIVE)
					body.setLive(body.live - Math.round(body.maxLive / 5));
				else {
					if (actionName == ACTION_WEAPONTNEXT) 
						changeActionState(ACTION_WEAPONT, body.nextWeapont);
					else if (actionName == ACTION_WEAPONTPREV)
						changeActionState(ACTION_WEAPONT, body.prevWeapont);
				}
			}
			return true;
		}
		
		override public function typeFromRadar(): int {
			return df_radarEvent.TYPE_NETCHIP;
		}
		
		override protected function calculate():void {
			super.calculate();
			
			if (keyState[ACTION_FORWARD]) {
				if (_moveRequest < body.options.maxSpeed)
					_moveRequest += (body.options.maxSpeed - _moveRequest) * Space.options.chipACCEL;
			} else if (keyState[ACTION_BACKWARD]) {
				if (-_moveRequest < body.options.maxSpeed)
					_moveRequest -= (body.options.maxSpeed - Math.abs(_moveRequest)) * Space.options.chipACCEL;
			} else  _moveRequest *= (1 - Space.options.chipTORMOS);
			
			if (keyState[ACTION_SLIDERIGHT]) {
				if (_slideRequest < body.options.maxSpeed)
					_slideRequest += (body.options.maxSpeed - _slideRequest) * Space.options.chipACCEL;
			} else if (keyState[ACTION_SLIDELEFT]) {
				if (-_slideRequest < body.options.maxSpeed)
					_slideRequest -= (body.options.maxSpeed - Math.abs(_slideRequest)) * Space.options.chipACCEL;
			} else  _slideRequest *= (1 - Space.options.chipTORMOS);
			
			if (keyState[ACTION_LEFTROLL]) {
				if (_rotateRequest.z < Space.options.chipMAXROLL)
					_rotateRequest.z += (Space.options.chipMAXROLL - _rotateRequest.z) * Space.options.chipACCEL;
			} else if (keyState[ACTION_RIGHTROLL]) {
				if (-_rotateRequest.z < Space.options.chipMAXROLL)
					_rotateRequest.z -= (Space.options.chipMAXROLL - _rotateRequest.z) * Space.options.chipACCEL;
			} else _rotateRequest.z *= (1 - Space.options.chipTORMOS);
			
			if (keyState[ACTION_ROTAX]) {
				if (_rotateRequest.x < Space.options.chipMAXROLL)
					_rotateRequest.x += (Space.options.chipMAXROLL - _rotateRequest.x) * Space.options.chipACCEL;
			} else if (keyState[ACTION_ROTDX]) {
				if (-_rotateRequest.x < Space.options.chipMAXROLL)
					_rotateRequest.x -= (Space.options.chipMAXROLL - _rotateRequest.x) * Space.options.chipACCEL;
			} else _rotateRequest.x *= (1 - Space.options.chipTORMOS);			
			
			if (keyState[ACTION_ROTAY]) {
				if (_rotateRequest.y < Space.options.chipMAXROLL)
					_rotateRequest.y += (Space.options.chipMAXROLL - _rotateRequest.y) * Space.options.chipACCEL;
			} else if (keyState[ACTION_ROTDY]) {
				if (-_rotateRequest.y < Space.options.chipMAXROLL)
					_rotateRequest.y -= (Space.options.chipMAXROLL - _rotateRequest.y) * Space.options.chipACCEL;
			} else _rotateRequest.y *= (1 - Space.options.chipTORMOS);
		}
		
		override protected function doFrame():void {
			super.doFrame();
			if (body) body.attachToVector(Vector3D.Y_AXIS);
		}
	}
}